/**
 * Created by Administrator on 2015/9/2.
 */
var redis = require('redis');
var uuid = require('node-uuid');
var poolModule = require('generic-pool');
var pool = poolModule.Pool({
    name: 'redisPool',
    create: function (callback) {
        var client = redis.createClient();
        callback(null, client);
    },
    destroy: function (client) {
        client.quit();
    },
    max: 100,
    min: 5,
    idleTimeoutMillis: 3000,
    log: true
});

//扔一个瓶子
function throwOneBottle(bottle, callback) {
    bottle.time = bottle.time || Date.now();
    //随机生成一个id
    var bottleId = uuid.v4();
    var type = {male: 0, female: 1};
    pool.acquire(function (err, client) {
        if(err) {
            return callback({code: 0, msg: err});
        }
        client.SELECT(type[bottle.type], function () {
            client.HMSET(bottleId, bottle, function (err, result) {
                if(err) {
                    return callback({code: 0, msg: '过会儿再试试吧!'});
                }
                //设置漂流瓶生存时间,一天，  expire 与 pexpire 的区别是：前者以秒为单位，后者以毫秒为单位
                client.PEXPIRE(bottleId, 86400000 + bottle.time - Date.now(), function () {
                    //释放连接
                    pool.release(client);
                });
                callback({code:1, msg:result});
            })
        })

    })
}

//捡一个瓶子
function pickOneBottle(info,callback) {
    var type = {all: Math.round(Math.random()), male: 0, female: 1};
    info.type = info.type || 'all';
    pool.acquire(function (err, client) {
        //根据请求的瓶子类型到不同的数据库中取
        client.SELECT(type[info.type], function () {
            client.RANDOMKEY(function (err, bottleId) {
                if (err) {
                    return callback({code: 0, msg: err});
                }
                if (!bottleId) {
                    return callback({code: 1, msg: '海星'});
                }
                //根据漂流瓶id渠道漂流瓶完整信息
                client.HGETALL(bottleId, function (err, bottle) {
                    if (err) {
                        return callback({code: 0, msg: '漂流瓶破损了...'});
                    }
                    //从Redis中删除该漂流瓶
                    client.DEL(bottleId, function () {
                        //释放连接
                        pool.release(client);
                    });
                    //返回结果，成功时包含捡到的漂流瓶信息
                    callback({code: 1, msg: bottle});
                });
            });
        });
    });
}

function checkPickTimes(owner,callback) {
    pool.acquire(function (err, client) {
        if (err) {
            return callback({code: 0, msg: err});
        }
        //到2号数据库检查用户是否超过扔瓶次数限制
        client.SELECT(2, function () {
            //获取该用户捡瓶次数
            client.GET(owner, function (err, result) {
                if (result >= 10) {
                    return callback({code: 0, msg: '今天扔瓶子的机会已经用完啦'});
                }
                //捡瓶次数加1
                client.INCR(owner, function () {
                    // 检查是否是当天第一次扔瓶子
                    // 若是，则设置记录该用户扔瓶次数键的生存期为 1 天
                    // 若不是，生存期保持不变
                    client.TTL(owner, function (err, ttl) {
                        if (ttl === -1) {
                            client.EXPIRE(owner, 86400, function () {
                                //释放连接
                                pool.release(client);
                            });
                        } else {
                            pool.release(client);
                        }
                        callback({code: 1, msg: ttl});
                    });
                });
            });
        });
    });
}

function checkPickTimes(owner,callback) {
    pool.acquire(function (err, client) {
        if (err) {
            return callback({code: 0, msg: err});
        }
        // 到 3 号数据库检查用户是否超过捡瓶次数限制
        client.select(3, function () {
            //获取该用户捡瓶次数
            client.get(owner, function (err, result) {
                if (result >= 10) {
                    return callback({code: 0, msg: '今天捡瓶子的机会已经用完了'})
                }
                //捡瓶子次数加1
                client.incr(owner, function () {
                    // 检查是否是当天第一次捡瓶子
                    // 若是，则设置记录该用户捡瓶次数键的生存期为 1 天
                    // 若不是，生存期保持不变
                    client.TTL(owner, function (err, ttl) {
                        if (ttl === -1) {
                            client.EXPIRE(owner, 86400, function () {
                                // 释放连接
                                pool.release(client);
                            });
                        } else {
                            // 释放连接
                            pool.release(client);
                        }
                        callback({code: 1, msg: ttl});
                    });
                });
            });
        });
    });
}

exports.pick = function (info, callback) {
    checkPickTimes(info.user, function (result) {
        if (result.code === 0) {
            return callback(result);
        }
        //20%概率捡到海星
        if (Math.random() <= 0.2) {
            return callback({code: 1, msg: '海星'});
        }
        pickOneBottle(info, function (result) {
            callback(result);
        });
    });
};

exports.throw = function (bottle, callback) {
    checkThrowTimes(bottle.owner, function (result) {
        if (result.code === 0) {
            return callback(result);
        }
        throwOneBottle(bottle, function (result) {
            callback(result);
        });
    });
};
